//
//  HHContentView.m
//  Flower
//
//  Created by 花花 on 2016/12/5.
//  Copyright © 2016年 花花. All rights reserved.
//

#import "HHContentView.h"

@interface HHContentView ()<UIScrollViewDelegate, UICollectionViewDelegate, UICollectionViewDataSource>{

    CGFloat _oldOffSetX;
    BOOL _isLoadFirstView;

}
@property(nonatomic, weak) HHScrollSegmentView *segmentView;

//用于处理重用和内容的显示
@property(nonatomic, strong) HHCollectionView *collectionView;

//collectionView的布局
@property(nonatomic, strong) UICollectionViewFlowLayout *collectionViewLayout;

//父类 用于处理添加自控制器 使用weak避免循环引用
@property(nonatomic, weak) UIViewController *parentViewController;

//当这个属性设置为YES的时候， 就不用处理  scrollView滚动的计算
@property(nonatomic,assign)BOOL forbidTouchToAdjustPostion;
@property(nonatomic,assign)NSInteger itemsCount;

//所有的自控制器
@property(nonatomic, strong) NSMutableDictionary<NSString *,UIViewController<HHScrollPageViewChildDelegate>*> *childVcsDic;

//当前控制器

@property(nonatomic, strong) UIViewController<HHScrollPageViewChildDelegate> *currentChildVc;

/// 如果类似cell缓存一样, 虽然创建的控制器少了, 但是每个页面每次都要重新加载数据, 否则显示的内容就会出错, 貌似还不如每个页面创建一个控制器好
//@property (strong, nonatomic) NSCache *cacheChildVcs;

@property(nonatomic,assign)NSInteger currentIndex;
@property(nonatomic,assign)NSInteger oldIndex;
@property(nonatomic,assign)BOOL needManageLifeCycle;
@property(nonatomic,assign)BOOL changeAnimated;

@end
static NSString *const cellID = @"cellID";
static NSString *const kContentOffsetOffKey = @"kContentOffsetOffKey";

@implementation HHContentView
//初始化方法

- (instancetype)initWithFrame:(CGRect)frame segmentView:(HHScrollSegmentView *)segmentView parentViewController:(UIViewController *)parentViewController

                     delegate:(id<HHScrollPageViewDelegate>)delegate{


    if (self = [super initWithFrame:frame]) {
        self.segmentView = segmentView;
        self.delegate = delegate;
        self.parentViewController = parentViewController;
        _needManageLifeCycle =![parentViewController shouldAutomaticallyForwardAppearanceMethods];
        
        if (!_needManageLifeCycle) {
#if DEBUG
              NSLog(@"\n请注意: 如果你希望所有的子控制器的view的系统生命周期方法被正确的调用\n请重写%@的'shouldAutomaticallyForwardAppearanceMethods'方法 并且返回NO\n当然如果你不做这个操作, 子控制器的生命周期方法将不会被正确的调用\n如果你仍然想利用子控制器的生命周期方法, 请使用'ZJScrollPageViewChildVcDelegate'提供的代理方法\n或者'ZJScrollPageViewDelegate'提供的代理方法", [parentViewController class]);
#endif
        
        }
        
        [self commonInit];
        [self addNotifocation];
    }
    
    return self;
    

}

-(void)commonInit{
    
    _oldIndex = -1;
    _currentIndex = 0;
    _oldOffSetX = 0.0f;
    _forbidTouchToAdjustPostion = NO;
    _isLoadFirstView = YES;

    if ([_delegate  respondsToSelector:@selector(numberOfChildViewControllers)]) {
        self.itemsCount = [_delegate numberOfChildViewControllers];
    }

    [self addSubview:self.collectionView];
    
    UINavigationController *nav =(UINavigationController *)self.parentViewController.parentViewController;
    
    if ([nav isKindOfClass:[UINavigationController class]]) {
        
        if (nav.interactivePopGestureRecognizer) {
            
            __weak typeof (self) weakSelf = self;
            
            [_collectionView setScrollViewShouldBeginPanGestureHandler:^BOOL(HHCollectionView *collectionView, UIPanGestureRecognizer *panGesture) {
               
                CGFloat transionX = [panGesture translationInView:panGesture.view].x;
                
                if (collectionView.contentOffset.x == 0 && transionX >0) {
                    nav.interactivePopGestureRecognizer .enabled = YES;
                }else{
                
                    nav.interactivePopGestureRecognizer.enabled = NO;
                }
                if (weakSelf.delegate &&[weakSelf.delegate respondsToSelector:@selector(scrollPageController:contentScrollView:shouldBeginPanGesture:)]) {
                    return [weakSelf.delegate scrollPageController:weakSelf.parentViewController contentScrollView:collectionView shouldBeginPanGesture:panGesture];
                }
                
                return YES;
                
            }];
        }
    }
}

-(void)addNotifocation{

    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(receiveMemoryWarningHader:) name:UIApplicationDidReceiveMemoryWarningNotification object:nil];
    

}
-(void)dealloc{

    self.parentViewController = nil;
    [[NSNotificationCenter defaultCenter]removeObserver:self];
#if DEBUG
    NSLog(@"ZJContentView---销毁");
#endif
    

}
-(void)receiveMemoryWarningHader:(NSNotificationCenter *)not{

    __weak typeof (self) weakSelf = self;
    
    [_childVcsDic enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, UIViewController<HHScrollPageViewChildDelegate> * _Nonnull childVc, BOOL * _Nonnull stop) {
       
        __strong typeof (self) strongSelf = weakSelf;
        if (childVc != strongSelf.currentChildVc) {
            
            [_childVcsDic removeObjectForKey:key];
            [HHContentView removeChildVc:childVc];
            
        }
    }];


}
+(void)removeChildVc:(UIViewController *)childVc{

    [childVc willMoveToParentViewController:nil];
    [childVc.view removeFromSuperview];
    [childVc removeFromParentViewController];
    
}
-(void)layoutSubviews{

    [super layoutSubviews];
    if (self.currentChildVc) {
        self.currentChildVc.view.frame = self.bounds;
    }

}
//给外界可以设置ContentOffSet的方法
-(void)setContentOffSet:(CGPoint)offset animated:(BOOL)animated{
    
    self.forbidTouchToAdjustPostion = YES;
    
    NSInteger currentIndex = offset.x/self.collectionView.bounds.size.width;
    _oldIndex = _currentIndex;
    
    self.currentIndex = currentIndex;
    _changeAnimated = YES;
    
    if (animated) {
        CGFloat delta = offset.x - self.collectionView.contentOffset.x;
        NSInteger page = fabs(delta)/self.collectionView.bounds.size.width;
        
        if (page>=2) { //需要滚动两页以上的时候，跳过中间页的动画
            _changeAnimated = NO;
            __weak typeof(self) weakSelf = self;
            dispatch_async(dispatch_get_main_queue(), ^{
                __strong typeof(weakSelf)strongSelf = weakSelf;
                if (strongSelf) {
                    [strongSelf.collectionView setContentOffset:offset animated:YES];
                }
            });
        }else{
        
            [self.collectionView setContentOffset:offset animated:YES ];
        }
        
        
    }else{
    
            [self.collectionView setContentOffset:offset animated:YES ];
    }
    

}

//给外界 重新加载内容的方法
- (void)reload{
[self.childVcsDic enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, UIViewController<HHScrollPageViewChildDelegate> * _Nonnull childVc, BOOL * _Nonnull stop) {
    [HHContentView removeChildVc:childVc];
    childVc = nil;
    
}];
    
    self.childVcsDic = nil;
    [self.collectionView reloadData];
    [self commonInit];
    
}

#pragma mark - <UIScrollViewDelegate>
-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{

    _oldOffSetX = scrollView.contentOffset.x;
    self.forbidTouchToAdjustPostion = NO;
    

}


-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
    if (self.forbidTouchToAdjustPostion || //点击标题滚动
        scrollView.contentOffset.x<=0 || //
        scrollView.contentOffset.x>= scrollView.contentSize.width-scrollView.bounds.size.width) {
        return;
    }
    
    CGFloat tempProgress = scrollView.contentOffset.x/self.bounds.size.width;
    NSInteger tempIndex = tempProgress;
    CGFloat progress = tempProgress - floor(tempProgress);
    CGFloat deltaX = scrollView.contentOffset.x - _oldOffSetX;
    
    
    if (deltaX>0) { //向右
        if (progress == 0.0) {
            return;
        }
        self.currentIndex = tempIndex +1;
        self.oldIndex= tempIndex;
        
    }else if (deltaX<0){
        progress = 1.0 -progress;
        self.oldIndex = tempIndex+1;
        self.currentIndex = tempIndex;
    
    }else{
        return;
    }
    
    [self contentViewDidMoveFromIndex:_oldIndex toIndex:_currentIndex progress:progress];

}


//滚动减速完成时再更新titled的位置
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{

    NSInteger currentIndx = scrollView.contentOffset.x/scrollView.width;
    
    //调整title
    [self adjustSegmentTitleOfOffsetToCurrentIndex:currentIndx];
    
}

-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{

    UINavigationController *nav =(UINavigationController *)self.parentViewController.parentViewController;
    
    if ([nav isKindOfClass:[UINavigationController class]]&& nav.interactivePopGestureRecognizer) {
        nav.interactivePopGestureRecognizer.enabled = YES;
    }

}
-(void)contentViewDidMoveFromIndex:(NSInteger)formIndex toIndex:(NSInteger)toIndex progress:(CGFloat)progress{

    if (self.segmentView) {
        [self.segmentView adjustUIWithProgress:progress oldIndex:formIndex currentIndex:toIndex];
    }

}
-(void)adjustSegmentTitleOfOffsetToCurrentIndex:(NSInteger)index{

    if (self.segmentView) {
        [self.segmentView adjustTitleOffSetToCurrentIndex:index];
    }
}

-(void)willAppearWithIndex:(NSInteger)index{
    UIViewController<HHScrollPageViewChildDelegate> *VC =[self.childVcsDic valueForKey:[NSString stringWithFormat:@"%zd",index]];
    if (VC) {
        if ([VC respondsToSelector:@selector(hh_viewWillAppearForIndex:)]) {
            [VC hh_viewWillAppearForIndex:index];
        }
        
        if (_needManageLifeCycle) {
            [VC beginAppearanceTransition:YES animated:NO];
        }
        
        if (_delegate && [_delegate respondsToSelector:@selector(scrollPageController:childViewControllWillAppear:forIndex:)]) {
            [_delegate scrollPageController:self.parentViewController childViewControllWillAppear:VC forIndex:index];
        }
    }

}
-(void)didAppearWithIndex:(NSInteger)index{
    UIViewController<HHScrollPageViewChildDelegate> *VC =[self.childVcsDic valueForKey:[NSString stringWithFormat:@"%zd",index]];
    
    if (VC) {
        if ([VC respondsToSelector:@selector(hh_viewDidAppearForIndex:)]) {
            [VC hh_viewDidAppearForIndex:index];
        }
        if (_needManageLifeCycle) {
            [VC endAppearanceTransition];
        }
        if (_delegate && [_delegate respondsToSelector:@selector(scrollPageController:childViewControllDidAppear:forIndex:)]) {
            [_delegate scrollPageController:self.parentViewController childViewControllDidAppear:VC forIndex:index];
            
        }
    }

}

-(void)willDisappearWithIndex:(NSInteger)index{
UIViewController<HHScrollPageViewChildDelegate> *VC =[self.childVcsDic valueForKey:[NSString stringWithFormat:@"%zd",index]];
    
    if (VC) {
        if ([VC respondsToSelector:@selector(hh_viewWillDisappearForIndex:)]) {
            [VC hh_viewWillDisappearForIndex:index];
        }
        if (_needManageLifeCycle) {
            [VC beginAppearanceTransition:YES animated:NO];
        }
        if (_delegate && [_delegate respondsToSelector:@selector(scrollPageController:childViewControllWillDisappear:forIndex:)]) {
            [_delegate scrollPageController:self.parentViewController childViewControllWillDisappear:VC forIndex:index];
        }
    }
}
-(void)didDisappearWithIndex:(NSInteger)index{
    UIViewController<HHScrollPageViewChildDelegate> *VC =[self.childVcsDic valueForKey:[NSString stringWithFormat:@"%zd",index]];
    
    if (VC) {
        if ([VC respondsToSelector:@selector(hh_viewDidDisappearForIndex:)]) {
            [VC hh_viewDidDisappearForIndex:index];
        }
        if (_needManageLifeCycle) {
            [VC endAppearanceTransition];
        }
        if (_delegate && [_delegate respondsToSelector:@selector(scrollPageController:childViewControllDidDisappear:forIndex:)]) {
            [_delegate scrollPageController:self.parentViewController childViewControllDidDisappear:VC forIndex:index];
        }
    }


}

#pragma mark - <UICollectionViewDelegate,UICollectionViewDataSource>
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{

    return _itemsCount;
}


- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{

    UICollectionViewCell *cell =[collectionView dequeueReusableCellWithReuseIdentifier:cellID forIndexPath:indexPath];
    
    //移除subViews 比年重用内容显现错误
    [cell.contentView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
    
    return cell;

}

- (void)collectionView:(UICollectionView *)collectionView willDisplayCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath
{

    NSLog(@"出现出现:current:---- %zd   old ----- %zd indexpathRow----%zd ", _currentIndex, _oldIndex, indexPath.row);

    _currentChildVc = [self.childVcsDic valueForKey:[NSString stringWithFormat:@"%zd",(long)indexPath.row]];
    BOOL isFirstLoaded = _currentChildVc ==nil;
    
    if (_delegate && [_delegate respondsToSelector:@selector(childViewController:forIndex:)]) {
        if (_currentChildVc ==nil) {
            _currentChildVc = [_delegate childViewController:nil forIndex:indexPath.row];
        
            if (!_currentChildVc || ![_currentChildVc conformsToProtocol:@protocol(HHScrollPageViewChildDelegate)]) {
                NSAssert(NO, @"子控制器必须遵守ZJScrollPageViewChildVcDelegate协议");
            }
            //设置当前下标
            _currentChildVc.hh_currentIndex = indexPath.row;
            [self.childVcsDic setValue:_currentChildVc forKey:[NSString stringWithFormat:@"%zd",(long)indexPath.row]];
            
        }else{
        
            [_delegate childViewController:_currentChildVc forIndex:indexPath.row];
        }
    }else{
        NSAssert(NO, @"必须设置代理和实现代理方法");
       
    }
     //// 这里建立子控制器和父控制器的关系
    
    if ([_currentChildVc isKindOfClass:[UINavigationController class]]) {
        NSAssert(NO, @"不要添加UINavigationController包装后的子控制器");
    }
    
    if (_currentChildVc.hh_scrollViewController != self.parentViewController) {
        [self.parentViewController addChildViewController:_currentChildVc];
    }
    _currentChildVc.view.frame = self.bounds;
    [cell.contentView addSubview:_currentChildVc.view];
    [_currentChildVc didMoveToParentViewController:self.parentViewController];
        NSLog(@"当前的index:%zd", indexPath.row);
    
    if (_isLoadFirstView) {
        if (self.forbidTouchToAdjustPostion && !_changeAnimated) {
            [self willAppearWithIndex:_currentIndex];
            if (isFirstLoaded) {
                if ([_currentChildVc respondsToSelector:@selector(hh_viewDidLoadForIndex:)]) {
                    
                    [_currentChildVc hh_viewDidLoadForIndex:indexPath.row];
                }
            }
            [self didAppearWithIndex:_currentIndex];
        }else{
        
            [self willAppearWithIndex:indexPath.row];
            
            if (isFirstLoaded) {
                if ([_currentChildVc respondsToSelector:@selector(hh_viewDidLoadForIndex:)]) {
                    [_currentChildVc hh_viewDidLoadForIndex:indexPath.row];
                }
            }
            [self didAppearWithIndex:indexPath.row];
        
        }
        _isLoadFirstView =NO;
        
    }else{
        if (self.forbidTouchToAdjustPostion && !_changeAnimated) {
            [self willAppearWithIndex:_currentIndex];
            if (isFirstLoaded) {
                if ([_currentChildVc respondsToSelector:@selector(hh_viewDidLoadForIndex:)]) {
                    
                    [_currentChildVc hh_viewDidLoadForIndex:indexPath.row];
                }
            }
            [self didAppearWithIndex:_currentIndex];
        }else{
            
            [self willAppearWithIndex:indexPath.row];
            
            if (isFirstLoaded) {
                if ([_currentChildVc respondsToSelector:@selector(hh_viewDidLoadForIndex:)]) {
                    [_currentChildVc hh_viewDidLoadForIndex:indexPath.row];
                }
            }
            [self willDisappearWithIndex:_oldIndex];

        }
        
    
    }
    
    
}
//已经展示某个Item时触发的方法
- (void)collectionView:(UICollectionView *)collectionView didEndDisplayingCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath{
    NSLog(@"消失消失:current:---- %zd   old ----- %zd indexpathRow----%zd ", _currentIndex, _oldIndex, indexPath.row);

    if (_currentIndex == indexPath.row) { //没有滚动完成
        if (_needManageLifeCycle) {
            UIViewController<HHScrollPageViewChildDelegate> *currentVc =[self.childVcsDic valueForKey:[NSString stringWithFormat:@"%zd",_currentIndex]];
            
            //开始出现
            [currentVc beginAppearanceTransition:YES animated:NO];
          
            UIViewController<HHScrollPageViewChildDelegate> *oldVc =[self.childVcsDic valueForKey:[NSString stringWithFormat:@"%zd",indexPath.row]];
            
            //开始消失
            [oldVc beginAppearanceTransition:NO animated:NO];
            
        }
        [self didAppearWithIndex:_currentIndex];
        [self didDisappearWithIndex:indexPath.row];
        
        
        
    }else{
        
        if (_oldIndex ==indexPath.row) {
            //g滚动完成
            if (self.forbidTouchToAdjustPostion && !_changeAnimated) {
                [self willDisappearWithIndex:_oldIndex];
                [self didDisappearWithIndex:_oldIndex];
            }else{
            
                [self didAppearWithIndex:_currentIndex];
                [self didDisappearWithIndex:indexPath.row];
            }
        }else{ // 滚动没有完成又快速的反向打开了另一页
        
            if (_needManageLifeCycle) {
                UIViewController<HHScrollPageViewChildDelegate> *currentVC =[self.childVcsDic valueForKey:[NSString stringWithFormat:@"%zd",(long)_oldIndex]];
                [currentVC beginAppearanceTransition:YES animated:NO];
             
                UIViewController<HHScrollPageViewChildDelegate> *oldVc =[self.childVcsDic valueForKey:[NSString stringWithFormat:@"%zd",(long)indexPath.row]];
                
                //开始消失
                [oldVc beginAppearanceTransition:NO animated:NO];
            }
            
            
            [self didAppearWithIndex:_oldIndex];
            [self didDisappearWithIndex:indexPath.row];
        
        
        }
    
    
    }
    
}
#pragma mark - Setter && Getter
-(void)setCurrentIndex:(NSInteger)currentIndex{
    if (_currentIndex != currentIndex) {
        _currentIndex = currentIndex;
        
        if (self.segmentView.segmentStyle.isAdjustTitleWhenBeginDrag) {

            [self adjustSegmentTitleOfOffsetToCurrentIndex:currentIndex];
        }
    }

}



-(HHCollectionView *)collectionView{
    
    if (!_collectionView) {
        HHCollectionView *collectionView =[[HHCollectionView alloc]initWithFrame:self.bounds collectionViewLayout:self.collectionViewLayout];
        [collectionView setBackgroundColor:[UIColor whiteColor]];
        collectionView.pagingEnabled = YES;
        collectionView.scrollsToTop = NO;
        collectionView.showsHorizontalScrollIndicator = NO;
        collectionView.delegate = self;
        collectionView.dataSource = self;
        collectionView.bounces = YES;
        [collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:cellID];
        collectionView.bounces = self.segmentView.segmentStyle.isContentViewBounces;
        collectionView.scrollEnabled = self.segmentView.segmentStyle.isScrollContentView;
        [self addSubview:collectionView];
        _collectionView = collectionView;
    }
    
    return _collectionView;
    
}

-(UICollectionViewFlowLayout *)collectionViewLayout{
    
    if (!_collectionViewLayout) {
        UICollectionViewFlowLayout *layout =[[UICollectionViewFlowLayout alloc]init];
        layout.itemSize = self.bounds.size;
        layout.minimumLineSpacing = 0.0;
        layout.minimumInteritemSpacing = 0.0;
        layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
        _collectionViewLayout = layout;
    }
    
    return _collectionViewLayout;
    
}

-(NSMutableDictionary<NSString *,UIViewController<HHScrollPageViewChildDelegate>*> *)childVcsDic{
    
    if (!_childVcsDic) {
        NSMutableDictionary *dic = [NSMutableDictionary dictionary];
        _childVcsDic = dic;
    }
    
    return _childVcsDic;
    
}
@end
